#region License
/* Copyright (c) 2011 Maksymilian Mulawa
	
Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice, 
 * this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright notice, 
 * this list of conditions and the following disclaimer in the documentation 
 * and/or other materials provided with the distribution.
   3. The name of the author may not be used to endorse or promote products 
 * derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#endregion

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Controls.WpfPropertyGrid;
using ReplicationExplorer.DomainModel.Infrastructure;
using ReplicationExplorer.DomainModel.Publisher.Entities;
using ReplicationExplorer.DomainModel.Subscriber.Models;

namespace ReplicationExplorer.DomainModel.Publisher.Models
{
    [CategoryOrder("Publication", 0)]
    [CategoryOrder("Publication stats", 1)]
    [CategoryOrder("Subscriptions", 2)]
    [CategoryOrder("Replication Agents", 3)]
    public class PublicationViewModel : TreeViewItemViewModel
    {
        private readonly Publication _publication;

        public PublicationViewModel(Publication publication, PublicationFolderViewModel parent, bool lazyLoadChildren)
            : base(parent, lazyLoadChildren)
        {
            _publication = publication;
            Children.Add(new SubscriptionFolderViewModel(this, true));
        }

        public override string ModelViewIcon
        {
            get
            {
                return "Publication.png";
            }
        }

        public override string ModelViewName
        {
            get
            {
                return "Publication";
            }
        }

        [Category("Publication")]
        [Description("Publication name")]
        [DisplayName(@"Publication name")]
        [ReadOnly(true)]
        [PropertyOrder(0)]
        public string Name
        {
            get { return _publication.Name; }
        }

        [Category("Publication")]
        [Description("Publication database name")]
        [DisplayName(@"Database name")]
        [ReadOnly(true)]
        [PropertyOrder(1)]
        public string PublicationDatabase
        {
            get { return _publication.PublicationDatabase; }
        }

        [Category("Publication")]
        [Description("Publication type")]
        [DisplayName(@"Publication type")]
        [ReadOnly(true)]
        [PropertyOrder(2)]
        public string PublicationType
        {
            get
            {
                string type;
                switch (_publication.PublicationType)
                {
                    case 0:
                        type = "Transactional";
                        break;
                    case 1:
                        type = "Snapshot";
                        break;
                    case 2:
                        type = "Merge";
                        break;
                    default:
                        type = "N/A";
                        break;
                }
                
                return type;
            }
        }

        [Category("Publication")]
        [Description("Description")]
        [DisplayName(@"Description")]
        [ReadOnly(true)]
        [PropertyOrder(3)]
        public string Description
        {
            get { return _publication.Description; }
        }


        [Category("Publication stats")]
        [Description("Status")]
        [DisplayName(@"Status")]
        [ReadOnly(true)]
        [PropertyOrder(0)]
        public string Status
        {
            get { return UI.StringConverter.ConvertPublisherStatus(_publication.Status); ; }
        }

        [Category("Publication stats")]
        [Description("Warning")]
        [DisplayName(@"Warning")]
        [ReadOnly(true)]
        [PropertyOrder(1)]
        public string Warning
        {
            get { return UI.StringConverter.ConvertPublisherWarning(_publication.Warning);; }
        }

        [Category("Publication stats")]
        [Description("The highest latency, in seconds, for data changes propagated by the Log Reader or Distribution Agents for a transactional publication.")]
        [DisplayName(@"Worst latency")]
        [ReadOnly(true)]
        [PropertyOrder(2)]
        public string WorstLatencyInSeconds 
        { 
            get
            {
                int? latencyInSeconds = _publication.WorstLatencyInSeconds;
                return latencyInSeconds.HasValue ?  string.Format("{0} seconds", latencyInSeconds) : "N/A";
            }
        }

        [Category("Publication stats")]
        [Description("The lowest latency, in seconds, for data changes propagated by the Log Reader or Distribution Agents for a transactional publication.")]
        [DisplayName(@"Best latency")]
        [ReadOnly(true)]
        [PropertyOrder(3)]
        public string BestLatencyInSeconds {
            get
            {
                int? latencyInSeconds = _publication.BestLatencyInSeconds;
                return latencyInSeconds.HasValue ? string.Format("{0} seconds", latencyInSeconds) : "N/A";
            }
        }

        [Category("Publication stats")]
        [Description("The average latency, in seconds, for data changes propagated by the Log Reader or Distribution Agents for a transactional publication.")]
        [DisplayName(@"Average latency")]
        [ReadOnly(true)]
        [PropertyOrder(4)]
        public string AvarageLatencyInSeconds
        {
            get
            {
                int? latencyInSeconds = _publication.AvarageLatencyInSeconds;
                return latencyInSeconds.HasValue ? string.Format("{0} seconds", latencyInSeconds) : "N/A";
            }
        }

        [Category("Replication Agents")]
        [Description("Last Distributor Agent run")]
        [DisplayName(@"Last Distributor Agent run")]
        [ReadOnly(true)]
        [PropertyOrder(4)]
        public string LastDistributorAgentRun
        {
            get
            {
                DateTime? lastDistributorAgentRun = _publication.LastDistributorAgentRun;
                return lastDistributorAgentRun.HasValue ? lastDistributorAgentRun.Value.ToString(CultureInfo.CurrentUICulture) : "N/A";
            }
        }

        [Category("Publication stats")]
        [Description("Retension period for publication.")]
        [DisplayName(@"Retension period")]
        [ReadOnly(true)]
        [PropertyOrder(4)]
        public string PublicationRetensionPeriodInHours
        {
            get { return UI.StringConverter.ConvertToHoursOrDays(_publication.PublicationRetensionPeriodInHours); }
        }
        
        

        [Category("Publication stats")]
        [Description("latency threshold set for the transactional publication.")]
        [DisplayName(@"Latency threshold")]
        [ReadOnly(true)]
        [PropertyOrder(5)]
        public string LatencyThreshold
        {
            get { return _publication.LatencyThreshold.HasValue ? UI.StringConverter.FormatToSeconds(_publication.LatencyThreshold.Value) : "N/A"; }
        }


        [Browsable(false)]
        public int? ExpirationThreshold { get; set; }

        [Category("Subscriptions")]
        [Description("Number of subscribers assigned to the publication")]
        [DisplayName(@"Number of subscribers")]
        [ReadOnly(true)]
        [PropertyOrder(0)]
        public int SubscriptionCount
        {
            get { return _publication.SubscriptionCount; }
        }

        [Category("Replication Agents")]
        [Description("Sql Server Agent job name that is running Snapshot Agent")]
        [DisplayName(@"Snapshot Agent")]
        [ReadOnly(true)]
        [PropertyOrder(2)]
        public string SnapshotAgentName
        {
            get { return _publication.SnapshotAgentName; }
        }
       
        [Category("Replication Agents")]
        [Description("Sql Server Agent job name that is running Log Reader Agent")]
        [DisplayName(@"Log Reader Agent")]
        [ReadOnly(true)]
        [PropertyOrder(1)]
        public string LogReaderAgentName
        {
            get { return _publication.LogReaderAgentName; }
        }

        [Category("Replication Agents")]
        [Description("Sql Server Agent job name that is running Queue Reader Agent")]
        [DisplayName(@"Queue Reader Agent")]
        [ReadOnly(true)]
        [PropertyOrder(3)]
        public string QueueReaderAgentName
        {
            get { return _publication.QueueReaderAgentName; }
        }

        [Category("Subscriptions")]
        [Description("Allows creation of push subscriptions to this publication")]
        [DisplayName(@"Allow push subscriptions")]
        [ReadOnly(true)]
        [PropertyOrder(1)]
        public string AllowPushSubscription 
        {
            get
            {
                bool? allow = _publication.AllowPushSubscription;
                return allow.HasValue ? UI.StringConverter.ConvertBoolToYesNo(allow.Value) : "N/A";
            }
        }

        [Category("Subscriptions")]
        [Description("Allows creation of pull subscriptions to this publication")]
        [DisplayName(@"Allow pull subscriptions")]
        [ReadOnly(true)]
        [PropertyOrder(2)]
        public string AllowPullSubscription
        {
            get
            {
                bool? allow = _publication.AllowPullSubscription;
                return allow.HasValue ? UI.StringConverter.ConvertBoolToYesNo(allow.Value) : "N/A";
            }
        }

        [Category("Subscriptions")]
        [Description("Allows creation of anonymous subscriptions to this publication")]
        [DisplayName(@"Allow anonymous subscriptions")]
        [ReadOnly(true)]
        [PropertyOrder(3)]
        public string AllowAnonymousSubscription
        {
            get
            {
                bool? allow = _publication.AllowAnonymousSubscription;
                return allow.HasValue ? UI.StringConverter.ConvertBoolToYesNo(allow.Value) : "N/A";
            }
        }

        [Category("Subscriptions")]
        [Description("Allows initializing subscription from backup")]
        [DisplayName(@"Allow initializing from backup")]
        [ReadOnly(true)]
        [PropertyOrder(3)]
        public string AllowSubscriptionInitializeFromBackup {
            get
            {
                bool? allow = _publication.AllowSubscriptionInitializeFromBackup;
                return allow.HasValue ? UI.StringConverter.ConvertBoolToYesNo(allow.Value) : "N/A";
            }
        }

        [Browsable(false)]
        public int SynchronizationMethod { get; set; }
        [Browsable(false)]
        public bool AllowSubscriptionDatabaseCopy { get; set; }
        [Browsable(false)]
        public bool AllowQueuedUpdates { get; set; }
        [Browsable(false)]
        public bool ImmediateSync { get; set; }

        [Browsable(false)]
        public Publication Source
        {
            get { return _publication; }
        }
    }

    
}